﻿#!/usr/bin/perl -w
#######################################################
# Create: P.Linux
# Function: Run DDL On Server List
# Usage: Run on any computer with Perl
# License: GPL v2
# Site: PengLiXun.COM
# Modify: 
# P.Linux 2010-03-10 
#    -Create 1.0 Release
########################################################
use strict;
use DBI;
use DBD::mysql;
use DBD::Oracle;
use Getopt::Std;
use vars qw($opt_l $opt_s $opt_t);
########################################################
# Global Status Var
# 全局状态变量
my @server_list;
my $sql;
# Connect to database via DBI
# 通过DBI连接数据库
my @dbconn;

# CmdLine Option vars
# 命令行参数变量
my($server_file, $sql_file, $db_type);

# Version
my $version='1.1 Release';

#######################################################
# Main Program
# 主程序
#######################################################

# Get CmdLine Options
# 获取命令行参数
&get_option();

# Read Server List From File
# 从文件中读取服务器列表
&read_file();

# Crate MySQL Database Connect
# 创建MySQL数据库连接
&create_conn();

# Run SQL
# 执行SQL
&run();

# Disconnect from MySQL
# 从数据库断开连接
&close_conn();

#######################################################
# Print Usage
# 打印使用方法
#######################################################
sub print_usage () {
        printf <<EOF
 NAME:
        mybatsql

 SYNTAX:
        mybatsql  -l server_file -s sql_file -t db_type

 FUNCTION:
        Run SQL on Server List

 PARAMETER:
      -l   Database Server List File DEFAULT:server.list
      -s   SQL File DEFAULT:sql.list
      -t   Database Type
EOF
}

#######################################################
# Get Options
# 获取命令行参数
#######################################################
sub get_option(){
    my $rtn = getopts('l:s:t');
    unless ( "$rtn" eq "1" ) { print_usage(); exit 1;}

    $server_file=$opt_l?$opt_l:'server.list';
    $sql_file=$opt_s?$opt_s:'sql.list';
    $db_type=$opt_t?$opt_t:'mysql';

    if($ARGV[0]){
        $server_file=$ARGV[0];
    }
    if($ARGV[1]){
        $sql_file=$ARGV[1];
    }
    if($ARGV[2]){
        $db_type=$ARGV[2];
    }

    $server_file = lc($server_file);
    $sql_file = lc($sql_file);
    $db_type = lc($db_type);
}

#######################################################
# Read Server List & SQL From File
# 从文件中读取服务器列表和SQL。
#######################################################
sub read_file{
    my $i;
    
    # Read Server List File
    open(FILE,"$server_file");
    $i = 0;     
    while(<FILE>){
        chomp;
        $server_list[$i] = [split(/,/,$_)];
	$i++;
    }

    close(FILE);
    # Read SQL List File
    open(FILE,"$sql_file");
    $i = 0;
    $sql = '';
    while(<FILE>){
	    chomp;
	    $sql .= $_;
	    $i++;
    }
    close(FILE);
}

#######################################################
# Create MySQL Database Connect 
# 创建MySQL数据库连接
#######################################################
sub create_conn{
    my $i = 0;
    foreach my $server (@server_list){
	    my @srv = @{$server};
	    my $host = $srv[0];
	    my $user = $srv[1];
	    my $pwd = $srv[2];
	    my $sid;
	    my $port;
	    if($db_type eq 'oracle') {
	        $sid = $srv[3];
		$port = $srv[4];
	    }
        #print "$host.$user.$pwd\n";
        eval{
            local $SIG{ALRM} = sub { die "连接数据库超时\n" };
            alarm 20;
	    if ($db_type eq 'mysql') {
                $dbconn[$i] = DBI->connect("DBI:mysql:host=$host", $user, $pwd, {'RaiseError' => 1}) 
                or die "Connect to $host error:". DBI->errstr;
	    }
	    if ($db_type eq 'oracle') {
                $dbconn[$i] = DBI->connect("DBI:Oracle:host=$host;sid=$sid;port=$port", $user, $pwd, {'RaiseError' => 1}) 
                or die "Connect to $host error:". DBI->errstr;
	    }
            alarm 0;
        };   
        if($@){
            printf "Connect to $host database error:".$@."\n";
            exit;
        }
        $i++;
    }
}

#######################################################
# Main Program to Run SQL on Server List
# 在服务器列表上执行一组SQL
#######################################################
sub run{
    foreach my $conn (@dbconn) {
        #print $sql;
        $conn->do($sql); 
        $conn->commit(); 
    }
}

#######################################################
# Disconnect from MySQL
# 从数据库断开连接
#######################################################
sub close_conn(){
    foreach my $conn (@dbconn) {
        $conn->disconnect;
    }
}
